这一篇学习笔记主要讲述的是在LNMP刚刚搭建完后需要做的一些常用的配置和优化。
1. 默认虚拟主机
和httpd类似,在Nginx中也有默认虚拟主机,第一个被Nginx加载的虚拟主机就是默认虚拟主机。但是和httpd不同的是,它还有一个配置用来标记默认虚拟主机。也就是说,如果没有这个标记,第一个虚拟主机为默认虚拟主机。
修改配置文件nginx.conf,在结束符号}
上面加入一行配置,改写如下:
意思是,/usr/local/nginx/conf/vhost/下面的所有以.conf
结尾的文件都会加载,这样我们就可以把所有虚拟主机配置文件放到vhost目录下面了。
|
|
2. 用户认证
再来创建一个新的虚拟主机:
上述配置说明:
- 核心配置语句就两行
auth_basic
打开认证auth_basic_user_file
指定用户密码文件,当然前提是这个用户密码文件存在。
- 生成用户密码文件的工具需要借助httpd的htpasswd,Nginx不自带这个工具。
- 第一次生成要用
-c
选项,第二次就不需要用了。
- 第一次生成要用
- 可以增加一句
root 绝对路径
来限制具体的路径。
下面使用curl工具来验证:
如果是用浏览器打开该网站,则会有提示框,输入用户名和密码,正确输入后才可以成功访问到网站的内容。
如果是针对某个目录做用户认证,需要修改location
后面的路径:
3. 域名重定向
Nginx的域名重定向和httpd的类似,但更容易理解,如下:
说明:
- 在Nginx配置中:
server_name
后面可以跟多个域名permanent
为永久重定向,相当于httpd的R=301
- 还有一个常用的
redirect
,相当于httpd的R=302
测试过程如下:
关于rewrite的一个应用——伪静态rewrite规则:
4. Nginx的访问日志
4.1. 配置Nginx的日志格式
先来看看Nginx的日志格式:
日志格式可以在Nginx.conf中自己定义,如下:
下面的日志格式,会记录代理的IP和真实客户端的真实IP,建议大家平时使用这个配置:
和httpd类似,也是在主配置文件中定义的日志格式。
combined_realip
为日志格式的名字,后面可以调用它$remote_addr
为访问网站的用户的出口IP$http_x_forwarded_for
为代理服务器的IP,如果使用了代理,则会记录代理的IP$time_local
为当前的时间$host
为访问的主机名$request_uri
为访问的URL地址$status
为状态码$http_referer
为referer地址$http_user_agent
为user_agent
然后再到虚拟主机配置文件中指定访问日志的路径:
使用access_log
来指定日志的存储路径,最后面指定日志的格式名字,测试过程如下:
4.2. 错误日志error_log日志级别
Nginx的error_log级别分为:debug
、info
、notice
、warn
、error
、crit
。默认为crit
。该日志级别在日志名后边的定义格式如下:
crit
记录的日志最少,而debug
记录的日志最多。如果你的Nginx遇到一些问题,比如502比较频繁出现,但是默认的error_log并没有看到有意义的信息,那么就可以调一下错误日志的级别,当你调成error
级别时,错误日志记录的内容会更加丰富。
4.3. 某些类型的文件不记录访问日志
配置如下:
详细的信息参考下面的《配置静态文件不记录访问日志并添加过期时间》章节。
4.4. Nginx的日志切割
Nginx的日志很简单,不像httpd还有自带的切割工具,要想切割Nginx日志需要借助系统的切割工具或者自定义脚本。
4.4.1. 切割脚本
在这里,用一个Nginx的日志切割脚本:
写完脚本后,还需要增加任务计划:
4.4.2. 借助系统的logrotate工具
配置过程如下:
说明:
- 第一行就要定日日志的路径,可以是多个日志。
daily
表示日志按天归档。missingok
表示忽略所有错误,比如日志文件不存在的情况下。rotate 52
表示存放的日志个数,最多就是52个,最老的会被删除。compress
表示日志要压缩。delaycompress
表示压缩除了当前和最近之外的所有其他版本。notifempty
表示如果日志为空,则不归档。create 644 nobody nobody
定义归档日志的权限以及属主和属组。sharedscripts
表示所有的日志共享该脚本,因为我们在这里指定的日志文件为多少个,用来*.log
。postrotate
后面跟轮换过日志之后要运行的命令。endscript
表示结束了。
5. 配置静态文件不记录访问日志并添加过期时间
需求和httpd中的一样,但是配置就简单很多,我们可以把指定文件类型不记录访问日志和配置静态文件过期时间的功能一起配置。虚拟主机的配置文件改成如下:
说明:
- 使用
location ~
可以指定对应的静态文件 expires
配置过期时间access_log
配置为off
就可以不记录访问日志了
下面来模拟测试以一下:
可以很清楚地看到Cache-cpntrol
对应的时间大小。另外也可以看一下访问日志:
前面的实践中访问了js以及jpg类型的文件,都没有记录到日志里面去,可以看到我们配置的效果实现了。
6. Nginx防盗链
思路和httpd的一样,配置也不难,由于和过期时间、不记录日志有部分重合,可以把两部分组合在一起:
测试过程如下:
可以看到不仅仅有过期时间,还有防盗链的功能。也就是说,这些功能可以合在一起写。
7. 控制访问
和httpd一样,Nginx也需要限制某些IP不能访问或者只允许某些IP访问。配置方法和httpd很像,但更加简洁,而且不像httpd那样全部遍历一遍。比如,我们有个需求:使访问admin目录的请求只允许192.168.1.111和127.0.0.1访问。配置文件如下:
在配置httpd的时候,还有一个oeder,来先定义先allow还是先deny,在Nginx里并没有,只要匹配规则就结束了。假如来源IP为192.168.1.111,它会从上到下逐一去匹配,第一个IP(192.168.1.1)不符合,第二个IP(127.0.0.1)也不符合,直到第三行(all)的时候才匹配到,匹配的这条规则为deny(也就是拒绝访问),所以最红会返回一个403的状态码。如下所示:
配置文件中的IP也可以为IP段,比如可以写成allow 192.168.1.0/24
。如果只拒绝某几个IP,就可以写成这样了:
如果是黑名单的形式,就需要写allow all
了,因为默认就是允许所有。除了这种简单的限制目录外,也可以根据正则匹配来限制,如下:
小括号里面的竖线为分隔符,它们之间是或者的意思,这样就可以把访问的URL中带有abc或者image字符串,并且是PHP的请求拒绝访问。若是想把上传文件的目录禁止解析PHP,在Nginx的配置中,只需要这样几行就可以做到。
在Nginx的配置里,也可以针对user_agent做一些限制,工作中平时用得非常多。配置如下:
其中~
为匹配符号,只要user_agent
中含有Spider/3.0
或者YoudaoBot
或者Tomato
字符串的,都会被拒绝,return 403
为直接返回403的状态码,当然也可以把它替换为deny all
。
8. Nginx解析PHP
8.1. 配置Nginx解析PHP
在LAMP中,PHP是作为httpd的一个模块出现的,只要PHP模块被加载,那么就能解析PHP脚本了。而在LNMP中,PHP是以一个服务(php-fpm)的形式存在的,首先要启动php-fpm服务,然后Nginx再和php-fpm服务通信,也就是说,处理PHP脚本解析的工作是由php-fpm来完成的,Nginx仅仅是一个搬运工,它把用户的请求传递给php-fpm,php-fpm处理完成后把结果传递给Nginx,Nginx再把结果返回给用户。那么Nginx是如何和PHP联系起来的呢?其实,在nginx.conf中已经有了展示。
下面是test.com.conf的内容,其中包含了PHP相关的配置:
说明:
- 其中,
fastcgi_pass
用来指定php-fpm的地址,如果php-fpm监听的是一个tcp:port
的地址(比如127.0.0.1:9000),那么也需要在这里改成fastcgi_pass 127.0.0.1:9000
。这个地址一定要和php-fpm服务监听的地址匹配,否则会报502错误。 - 还有一个地方需要注意,
fastcgi_param SCRIPT_FILENAME
后面跟的路径为该站点的根目录,和前面定义的root
那个路径保持一致。如果这里配置不对,访问PHP页面会出现404。
8.2. 针对目录限制PHP解析
示例配置如下:
9. Nginx禁止指定user_agent
和httpd的相关配置也挺像,具体如下:
10. Nginx代理
10.1. Nginx代理
Nginx的代理功能非常实用,这也是Nginx比httpd越来越受欢迎的一个原因。一家公司有很多台服务器,为了节省成本,不能为所有服务器都分配公网IP,而如果一个没有公网IP的服务要提供Web服务,就可以通过代理来实现。
如果Nginx后面有多台Web服务器,如果同时代理,那Nginx在这里还可以用upstream起到一个负载均衡的作用,这个功能在生产环境中用得也特别多。
先来看一下Nginx的代理如何配置:
上述配置内容的说明:
- 前面两行不用解释,和普通的虚拟主机一样,不同的是后面proxy相关的语句。
proxy_pass
指定要代理的域名所在的服务器IP,这里的IP是阿铭论坛所在服务器的IP,可以通过ping ask.apelearn.com
获取到该IP。- 后面的三行为定义发往后端Web服务器的请求头,第二行必须有,否则代理不成功,它表示后端Web服务器的域名和当前配置文件中的
server_name
保持一致。第三行和第四行可以省略,在前面讲述Nginx日志格式的时候介绍过这两个参数,表示的含义是一样的。
配置文件保存后,重新加载Nginx服务并验证:‘
这样看是没有问题的,虚拟机的Nginx版本为1.10.3,而阿铭论坛服务器上用的是1.8.0。其实,把服务器上的环境版本暴漏出来并不安全,因为这样别有用心的人会直接获取到服务器上的软件版本信息,如果该版本正好有漏洞,那么他就可以直接攻击了。关于如何关掉版本信息,不再这里记录了。可以查取相关资料。
10.2. Nginx代理所有域名
我们还可以代理一个服务器上的所有域名。首先在vhost目录下需要创建两个文件,一个是servername列表文件,另一个是虚拟主机配置文件。两个文件内容分别如下:
servername
1234[root@localhost ~]server_name www.123.net.cn www.alsdjfl.com www.asdfal.com;- 就是这么简单一行,当然这个server_name后面还可以继续添加。
- 虚拟主机配置文件123456789101112131415161718[root@localhost ~]# vim /usr/local/nginx/conf/vhost/proxy_all.conf#<==加入如下内容server{listen 80;include vhosts/servername; #<==这里的文件就是上边那个servername列表文件location /{proxy_pass http://1.2.1.2/; #<==这里就是需要做代理的服务器IP了proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}access_log /dev/null;}
10.3. Nginx配置负载均衡
下面再提供一个负载均衡的示例,在编写Nginx虚拟主机配置文件之前,先来查看一下www.qq.com
域名对应的IP,使用dig
命令(若是没有这个命令,安装它yum install -y bind-utils
):
可以看到有两个IP,这两个IP都可以访问到www.qq.com。先来验证一下:
可以看到两个IP返回的结果是一样的,它使用的Web Server软件为squid(一种代理软件)。有两个IP就可以走负载均衡了,配置过程如下:
和简单的代理有所不同,负载均衡多了一个upstream,在这里定义后端的Web Server,可以是一个,也可以是多个。其中ip_hash
为负载均衡的算法,它表示根据IP地址把请求分到不通的服务器上。比如用户A的IP为1.1.1.1,用户B的IP为2.2.2.2,则A访问的时候会把请求转发到第一个Web Server上,而B访问的时候会到第二个Web Server上。这种算法用在把session存到本机磁盘上的情况,至于什么是session,其实就是访问信息,举个例子就像你登陆一个网站,服务器上就会记录你的session信息,这个session返回保存一段时间,等你休息一段时间后再看该网站,你会发现你还是登陆的状态,这就是因为session还存在这台服务器上。
下面是测试结果:
这样,虚拟机通过这种配置就可以访问www.qq.com了,这其实就是代理的作用。
11. Nginx配置SSL
HTTPS是一种加密的HTTP协议。如果HTTP通信的数据包在传输过程中被截取,我们可以破译这些数据包里面的信息,这里不乏一些用户名、密码、手机号等敏感信息。而如果使用HTTPS通信,即使数据包被截获,我们也无法破译里面的内容。
HTTPS的通信过程大致如下:
- 浏览器发送一个HTTPS请求给服务器
- 服务器要有一套数字整数,可以自己制作(后面的演示就是用的自己制作的整数),也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面,这套证书其实就是一对公钥和私钥。
- 服务器会把公钥传输给客户端
- 客户端(即浏览器)收到公钥后,会验证其是否合法有效,无效会有警告提醒,有效则会生成一串随机字符串,并用收到的公钥加密
- 客户端把加密后的随机字符串传输给服务器
- 服务器收到加密后的随机字符串后,先用私钥解密(公钥加密,私钥解密),获取到这一串随机字符串后,再用这串随机字符串加密传输的数据(该加密为”对称加密;所谓对称加密,就是将数据和私钥,也就是这个随机字符串通过某种算法混合在一起,这样除非知道私钥,否则无法获取数据内容”)
- 服务器把加密后的数据传输给客户端
- 客户端收到数据后,再用自己的私钥(也就是哪个随机字符串)解密。
通过上文的简要分析,我们可以确定服务器上必须有一对公钥和私钥,也就是后面提到的SSL证书。如果是公司的网站对外提供服务,则需要购买被各大浏览器厂商认可的SSL证书。目前各大SSL整数服务商已经不再提供免费的SSL整数服务,所以做本实验的时候,只能在Linux机器上生成一对自定义的SSL证书,这个证书只能我们自己玩一玩,不能使用在生产环境中。具体配置过程如下:
第一步
12345678[root@localhost vhost]# cd /usr/local/nginx/conf/[root@localhost conf]# openssl genrsa -des3 -out tmp.key 2048Generating RSA private key, 2048 bit long modulus....................+++........................................................................................................+++e is 65537 (0x10001)Enter pass phrase for tmp.key:Verifying - Enter pass phrase for tmp.key:- openssl命令如果没有安装,使用这个命令安装
yum install -y openssl
- 这一步是生成key文件(通常成为私钥)
- 2048为加密字符串长度
- 会提示让我们输入一个密码,密码不能太短,否则不成功
- openssl命令如果没有安装,使用这个命令安装
第二步
123[root@localhost conf]# openssl rsa -in tmp.key -out aminglinux.keyEnter pass phrase for tmp.key:writing RSA key- 这一步是把刚刚生成的tmp.key再转换成aminglinux.key,目的是删除刚才设置的密码
- 如果key文件有密码,则必须在Nginx加载它的时候输入它的密码,因此很不方便
第三步
123456789101112131415161718192021[root@localhost conf]# rm -f tmp.key[root@localhost conf]# openssl req -new -key aminglinux.key -out aminglinux.csrYou are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [XX]:State or Province Name (full name) []:Locality Name (eg, city) [Default City]:Organization Name (eg, company) [Default Company Ltd]:Organizational Unit Name (eg, section) []:Common Name (eg, your name or your server's hostname) []:aming.comEmail Address []:Please enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:123456An optional company name []:- 这一步是生成证书请求文件,这个并不是上文提到的公钥,但这个文件是必须要有的,我们要拿key文件和这个CSR文件一起生成最终的公钥文件。
- 其中
Common Name
为后面配置Nginx配置文件的server_name
第四步
1234[root@localhost conf]# openssl x509 -req -days 365 -in aminglinux.csr -signkey aminglinux.key -out aminglinux.crtSignature oksubject=/C=XX/L=Default City/O=Default Company Ltd/CN=aming.comGetting Private key- 这样最终才生成了CRT证书文件,也就是公钥。
以上操作的最终目的就是生成aminglinux.key
和aminglinux.crt
两个为念。其实购买的SSL证书主要是得到这两个文件,有了这两个文件就可以配置Nginx了。配置过程如下:
保存配置文件后,检查配置是否有问题:
果然配置有问题。通过错误提示,说明当前的Nginx并不支持SSL,这是因为在先前的Nginx编译时,并没有额外配置支持SSL的参数,要解决该问题只能重新百衲衣以便Nginx。操作过程如下:
编译重新安装完成后,再来检验一次:
发现没有问题后,创建对应的目录和测试文件:
再编辑真实机上的hosts文件,写入一行:
之后用浏览器访问https//aming.com/1.php即可看到效果。